package com.jzo2o.health.handler;

import com.jzo2o.api.trade.RefundRecordApi;
import com.jzo2o.api.trade.dto.response.ExecutionResultResDTO;
import com.jzo2o.api.trade.enums.RefundStatusEnum;
import com.jzo2o.common.expcetions.CommonException;
import com.jzo2o.common.expcetions.DBException;
import com.jzo2o.common.utils.CollUtils;
import com.jzo2o.common.utils.ObjectUtils;
import com.jzo2o.health.enums.OrderStatusEnum;
import com.jzo2o.health.model.domain.Orders;
import com.jzo2o.health.model.domain.OrdersCancelled;
import com.jzo2o.health.model.domain.OrdersRefund;
import com.jzo2o.health.properties.OrdersJobProperties;
import com.jzo2o.health.service.OrdersCancelledService;
import com.jzo2o.health.service.OrdersRefundService;
import com.jzo2o.health.service.OrdersService;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDate;
import java.time.temporal.Temporal;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 订单相关定时任务
 *
 * @author itcast
 * @create 2023/9/2 16:44
 **/
@Slf4j
@Component
public class OrdersHandler {

    @Resource
    private RefundRecordApi refundRecordApi;
    //解决同级方法调用，事务失效问题
    @Resource
    private OrdersHandler orderHandler;
    @Resource
    private OrdersJobProperties ordersJobProperties;
    @Autowired
    private OrdersService ordersService;
    @Autowired
    private OrdersCancelledService ordersCancelledService;
    @Autowired
    private ApplicationContext applicationContext;
    /**
     * 支付超时取消订单
     * 每分钟执行一次
     */
    @XxlJob(value = "cancelOverTimePayOrder")
    public void cancelOverTimePayOrder() {
        List<Orders> list = ordersService.list();
        if (CollUtils.isEmpty(list)) {
           throw new CommonException("订单不存在");
        }
        for (Orders orders : list) {
            Date startTime = orders.getCreateTime();
            Date endDate = new Date();
            long diffInMillies = Math.abs(endDate.getTime() - startTime.getTime());
            long minutes = TimeUnit.MILLISECONDS.toMinutes(diffInMillies);
            if (minutes>15 &&orders.getOrderStatus().equals(OrderStatusEnum.NO_PAY.getStatus())){
                OrdersCancelled ordersCancelled = ordersCancelledService.getById(orders.getId());
                if (ObjectUtils.isNotEmpty(ordersCancelled)){
                    throw new CommonException("订单已取消");
                }
                OrdersCancelled ordersCancelled1 = new OrdersCancelled();
                ordersCancelled1.setCancellerType(4);
                ordersCancelled1.setId(orders.getId());
                ordersCancelled1.setCancelReason("超时系统自动取消");
                ordersCancelled1.setCancelTime(LocalDate.now());
                OrdersHandler bean = applicationContext.getBean(OrdersHandler.class);
                bean.OverTimePayOrderForCancel(ordersCancelled1);
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void OverTimePayOrderForCancel(OrdersCancelled ordersCancelled){
        boolean save = ordersCancelledService.save(ordersCancelled);
        if (!save){
            throw new DBException("操作失败");
        }
        boolean update = ordersService.lambdaUpdate().set(Orders::getOrderStatus, OrderStatusEnum.CANCELLED.getStatus()).update();
        if (!update){
            throw new DBException("操作失败");
        }
    }

    @Autowired
    private OrdersRefundService ordersRefundService;
    /**
     * 订单退款异步任务
     */
    @XxlJob(value = "handleRefundOrders")
    public void handleRefundOrders() {
        List<Orders> list = ordersService.lambdaQuery().last("limit 100").list();
        if (CollUtils.isEmpty(list)){
            throw new CommonException("订单不存在");
        }
        for (Orders orders : list) {
            if (ObjectUtils.isNull(orders.getTransactionId())){
                throw new CommonException("订单不合法");
            }
            ExecutionResultResDTO executionResultResDTO = refundRecordApi.refundTrading(orders.getTradingOrderNo(), BigDecimal.valueOf(0.01));
            if (RefundStatusEnum.SENDING.getCode().equals(executionResultResDTO.getRefundStatus())){
                executionResultResDTO=refundRecordApi.refundTrading(orders.getTradingOrderNo(), BigDecimal.valueOf(0.01));
            }
            OrdersRefund ordersRefund = ordersRefundService.getById(orders.getId());
            if (ObjectUtils.isNotNull(ordersRefund)){
                throw new CommonException("订单无法退款或已退款");
            }
            if (RefundStatusEnum.SUCCESS.getCode().equals(executionResultResDTO.getRefundStatus())){
                OrdersRefund ordersRefund1 = new OrdersRefund();
                ordersRefund1.setId(orders.getId());
                ordersRefund1.setRealPayAmount( BigDecimal.valueOf(0.01));
                ordersRefund1.setTradingOrderNo(Long.valueOf(executionResultResDTO.getRefundNo()));
                ordersService.updateForRefund(ordersRefund1,executionResultResDTO,orders);
            }
        }
    }

    /**
     * 订单退款处理
     *
     * @param id                    订单id
     * @param executionResultResDTO 第三方退款信息
     */
    @Transactional(rollbackFor = Exception.class)
    public void refundOrder(Long id, ExecutionResultResDTO executionResultResDTO) {

    }
}
